home *** CD-ROM | disk | FTP | other *** search
- #include <storage.h>
- #include <strings.h>
- #include <math.h>
-
- #include <QuickDraw.h>
- #include <MacTypes.h>
- #include <FontMgr.h>
- #include <WindowMgr.h>
- #include <MenuMgr.h>
- #include <TextEdit.h>
- #include <DialogMgr.h>
- #include <EventMgr.h>
- #include <DeskMgr.h>
- #include <StdfilePkg.h>
- #include <FileMgr.h>
- #include <ToolboxUtil.h>
- #include <ControlMgr.h>
-
-
- #include "Harmonic.h"
-
- extern int errno; /* required by math lib */
- extern char gTAB[];
- extern char gCR[];
-
-
- /*
- Created by : Byro
- date : 03/05/90
- modified : 04/25/90
- */
-
- CalcHarmonic(Coeff, dampingCoeff, elasticConst, mass, initInterval,
- finalInterval, increment, xLbl, yLbl)
-
- double Coeff,
- dampingCoeff,
- elasticConst, /* comment later */
- mass;
- int initInterval,
- finalInterval,
- increment;
- char *xLbl,
- *yLbl;
-
- /*
- This section of code is the compute engine of the simple harmonic motion
- simulator application. It allocates storage, computes the function, and
- stores the data before returning to calling routine.
- */
-
- {
- double alpha,
- amplitude,
- beta,
- *dataPtr, /* used for dynamic storage of data pts */
- omega,
- *tPtr; /* used to free data ptr */
- int i,
- *t1Ptr,
- *timePtr;
-
- alpha = dampingCoeff / (2 * mass);
- omega = sqrt((double) (4 * mass * elasticConst - (dampingCoeff * dampingCoeff))) / (2 * mass);
- beta = dampingCoeff / (2 * mass * omega);
-
- /* allocate n + 1 doubles;SANE f.p. double uses 10 bytes per number */
-
- dataPtr = (double *) malloc((int) (((finalInterval / increment) * 10) + 10));
-
- /* allocate n + 2 ints; SANE ints use 2 bytes each */
-
- timePtr = (int *) malloc((int) (((finalInterval / increment) * 2) + 4));
-
- if ((dataPtr == NIL) || (timePtr == NIL))
- {
- /* display error dialog */
-
- NoteAlert(ENOUGH_ALERT, NIL);
- return;
- }
-
- tPtr = dataPtr; /* save ptr to alloced space to free correctly */
- t1Ptr = timePtr;
-
- for (i = initInterval; i <= finalInterval; i += increment)
- {
- /* note the values for cos and sin are in radians */
-
- amplitude = (Coeff * exp((double) (-alpha * i))) * (cos(omega * i)
- + beta * sin(omega * i));
-
- *dataPtr = amplitude; /* store value */
- *timePtr = i; /* store time interval */
- dataPtr++; timePtr++;
- }
- *timePtr = MinusOne; /* end of data delimiter */
-
- /*
- store labels x, y, and data into an ascii file . Note: floats must be
- converted to ascii before storing into file.
- Also free data ptr space on exit.
- */
- /* restore ptrs */
-
- dataPtr = tPtr;
- timePtr = t1Ptr;
-
- SaveToFile(xLbl, yLbl, dataPtr, timePtr);
- free(tPtr);
- free(t1Ptr);
- }
-
-
-
-
- SaveToFile(Xlbl, Ylbl, Dptr, Tptr)
- char *Xlbl,
- *Ylbl;
- double *Dptr;
- int *Tptr;
-
- /*
- This function converts the data pts to ascii and writes them to a
- text file along with their associated axis labels.
- */
-
- {
- double tmp;
- int fRefNum; /* file reference number */
- long count; /* buffer length */
- SFReply reply;
- static Str255 Fname = "\p"; /* initialize file name */
- static Point where = {100, 104};
- Str255 holder;
-
- SFPutFile(where, "\pSave File as:", "\pSim Result File", 0L, &reply);
- if (reply.good) /* cancel if button not pressed */
- {
- /* delete existing file */
-
- FSDelete(reply.fName, reply.vRefNum);
-
- /* create nu one */
-
- Create(reply.fName, reply.vRefNum, 'HSIM', 'TEXT');
- if (FSOpen(reply.fName, reply.vRefNum, &fRefNum) == noErr)
- {
- /* write axis labels into file */
-
- strcpy(holder, Xlbl); /* x-axis */
- count = strlen(holder);
- FSWrite(fRefNum, &count, holder);
- count = 1;
- FSWrite(fRefNum, &count, gCR); /* write nu line */
-
-
- strcpy(holder, Ylbl); /* y-axis */
- count = strlen(holder);
- FSWrite(fRefNum, &count, holder);
- count = 1;
- FSWrite(fRefNum, &count, gCR); /* write nu line */
-
-
- while (*Tptr != MinusOne)
- {
- if (*Dptr > 0)
- {
- /* save only + ive numbers */
-
- itoa((int) *Tptr, holder); /* convert time variable */
- count = strlen(holder);
- FSWrite(fRefNum, &count, holder); /* write time string */
-
- count = 1; /* write tab to file */
- FSWrite(fRefNum, &count, gTAB);
-
- tmp = ceil(*Dptr); /* round up to next highest int */
- itoa((int) tmp, holder); /* convert to ascii string */
- count = strlen(holder); /* compute buffer length */
- FSWrite(fRefNum, &count, holder); /* write out amplitude */
-
- count = 1;
- FSWrite(fRefNum, &count, gCR); /* write nu line */
- }
- Dptr++;
- Tptr++;
- }
-
- /* insures that buffer get written to disk */
-
- FlushVol("\p", reply.vRefNum);
- FSClose(fRefNum);
- }
- }
- }
-
-
-
-
- HandleDialog(settingsPtr)
- SavedSettingsPtr *settingsPtr;
-
- /*
- This funct handles the input of parameters via a dialog.
- */
-
- {
- int itemHit,
- dialogDone = FALSE,
- frictFlag = FALSE, ampFlag = FALSE, elastFlag = FALSE,
- startFlag = FALSE, finiFlag = FALSE, xFlag = FALSE, yFlag = FALSE,
- massFlag = FALSE, inkFlag = FALSE, simNameFlag = FALSE,
- itemType;
- Rect itemRect;
- Handle itemHandle;
- DialogPtr settingsDialog;
-
- doDialog(&settingsDialog); /* create dialog and load default setttings */
-
- /* init settingsPtr with default values here */
-
- SaveDefaults(&settingsDialog, settingsPtr);
- SelectWindow(settingsDialog);
- ShowWindow(settingsDialog); /* the dialog is initially invisible */
-
-
- while (dialogDone == FALSE)
- {
- ModalDialog(NIL, &itemHit);
- switch (itemHit)
- {
- case OK_BUTTON :
- HideWindow(settingsDialog);
- DisposDialog(settingsDialog);
- dialogDone = TRUE;
- break;
- case CANCEL_BUTTON :
- HideWindow(settingsDialog);
- DisposDialog(settingsDialog);
- dialogDone = TRUE;
- return(FALSE);
- break;
- case FRICTION_VALUE :
- if (frictFlag == FALSE)
- SelIText(settingsDialog, FRICTION_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, FRICTION_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).frict);
- frictFlag = TRUE;
- break;
- case AMPLITUDE_VALUE :
- if (ampFlag == FALSE)
- SelIText(settingsDialog, AMPLITUDE_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, AMPLITUDE_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).amp);
- ampFlag = TRUE;
- break;
- case ELASTIC_VALUE :
- if (elastFlag == FALSE)
- SelIText(settingsDialog, ELASTIC_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, ELASTIC_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).elastic);
- elastFlag = TRUE;
- break;
- case START_VALUE :
- if (startFlag == FALSE)
- SelIText(settingsDialog, START_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, START_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).start);
- startFlag = TRUE;
- break;
- case FINI_VALUE :
- if (finiFlag == FALSE)
- SelIText(settingsDialog, FINI_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, FINI_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).fini);
- finiFlag = TRUE;
- break;
- case X_VALUE :
- if (xFlag == FALSE)
- SelIText(settingsDialog, X_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, X_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).xVal);
- xFlag = TRUE;
- break;
- case Y_VALUE :
- if (yFlag == FALSE)
- SelIText(settingsDialog, Y_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, Y_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).yVal);
- yFlag = TRUE;
- break;
- case MASS_VALUE :
- if (massFlag == FALSE)
- SelIText(settingsDialog, MASS_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, MASS_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).mass);
- massFlag = TRUE;
- break;
- case INC_VALUE :
- if (inkFlag == FALSE)
- SelIText(settingsDialog, INC_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, INC_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).ink);
- inkFlag = TRUE;
- break;
- case SIM_NAME_VALUE :
- if (simNameFlag == FALSE)
- SelIText(settingsDialog, SIM_NAME_VALUE, MIN, MAX);
- /* get edited value */
- GetDItem(settingsDialog, SIM_NAME_VALUE, &itemType, &itemHandle,
- &itemRect);
- /* put it in ptr to struct */
- GetIText(itemHandle, &(**settingsPtr).simName);
- simNameFlag = TRUE;
- break;
-
- }
- } /* while */
- if (postProcess(settingsPtr) == FALSE) /* chk struct for invalid chars */
- {
- /* display error dialogs */
-
- Alert(PROCESS_ALERT, NIL);
- return(FALSE);
- }
-
- /* hndl x, y axis differential chk */
-
- if (validateX(settingsPtr) == FALSE)
- {
- NoteAlert(X_ALERT, NIL);
- return(FALSE);
- }
- if (validateY(settingsPtr) == FALSE)
- {
- NoteAlert(Y_ALERT, NIL);
- return(FALSE);
- }
-
- return(TRUE);
- }
-
-
-
-
- doDialog(SettingsDialog)
- DialogPtr *SettingsDialog;
-
- /*
- create dialog and load default strings.
- */
-
- {
- int itemType;
- Rect itemRect;
- Handle itemHandle;
- StringHandle DefFrictH,
- DefAmpH,
- DefElastH,
- DefStartH,
- DefFiniH,
- DefXH,
- DefYH,
- DefMassH,
- DefIncH,
- DefSimNameH;
-
- DefFrictH = GetString(DEF_FRICTION_ID); /* generate default string hndls */
- DefAmpH = GetString(DEF_AMPLITUDE_ID);
- DefElastH = GetString(DEF_ELASTIC_ID);
- DefStartH = GetString(DEF_START_ID);
- DefFiniH = GetString(DEF_FINI_ID);
- DefXH = GetString(DEF_X_AXIS_ID);
- DefYH = GetString(DEF_Y_AXIS_ID);
- DefMassH = GetString(DEF_MASS_ID);
- DefIncH = GetString(DEF_INC_ID);
- DefSimNameH = GetString(DEF_SIM_ID);
-
-
- *SettingsDialog = GetNewDialog(BASE_RES_ID, NIL, MOVE_TO_FRONT);
-
- if (*SettingsDialog == NIL)
- {
- /* display malloc dialog error */
-
- StopAlert(ENOUGH_ALERT, NIL);
- ExitToShell();
- }
-
- /* load default settings */
-
- GetDItem(*SettingsDialog, FRICTION_VALUE, &itemType, &itemHandle, &itemRect);
- HLock(DefFrictH);
- SetIText(itemHandle, *DefFrictH);
- HUnlock(DefFrictH);
-
- GetDItem(*SettingsDialog, AMPLITUDE_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefAmpH);
- SetIText(itemHandle, *DefAmpH);
- HUnlock(DefAmpH);
-
- GetDItem(*SettingsDialog, ELASTIC_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefElastH);
- SetIText(itemHandle, *DefElastH);
- HUnlock(DefElastH);
-
- GetDItem(*SettingsDialog, START_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefStartH);
- SetIText(itemHandle, *DefStartH);
- HUnlock(DefStartH);
-
- GetDItem(*SettingsDialog, FINI_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefFiniH);
- SetIText(itemHandle, *DefFiniH);
- HUnlock(DefFiniH);
-
- GetDItem(*SettingsDialog, X_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefXH);
- SetIText(itemHandle, *DefXH);
- HUnlock(DefXH);
-
- GetDItem(*SettingsDialog, Y_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefYH);
- SetIText(itemHandle, *DefYH);
- HUnlock(DefYH);
-
- GetDItem(*SettingsDialog, MASS_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefMassH);
- SetIText(itemHandle, *DefMassH);
- HUnlock(DefMassH);
-
- GetDItem(*SettingsDialog, INC_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefIncH);
- SetIText(itemHandle, *DefIncH);
- HUnlock(DefIncH);
-
- GetDItem(*SettingsDialog, SIM_NAME_VALUE, &itemType, &itemHandle, &itemRect);
-
- HLock(DefSimNameH);
- SetIText(itemHandle, *DefSimNameH);
- HUnlock(DefSimNameH);
- }
-
-
-
-
- SaveDefaults(myDialog, settings)
- DialogPtr *myDialog;
- SavedSettingsPtr *settings;
-
- /* puts default settings in structure */
-
- {
- int itemHit,
- itemType;
- Rect itemRect;
- Handle itemHndl;
-
- GetDItem(*myDialog, FRICTION_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).frict);
-
- GetDItem(*myDialog, AMPLITUDE_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).amp);
-
- GetDItem(*myDialog, ELASTIC_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).elastic);
-
- GetDItem(*myDialog, START_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).start);
-
- GetDItem(*myDialog, FINI_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).fini);
-
- GetDItem(*myDialog, X_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).xVal);
-
- GetDItem(*myDialog, Y_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).yVal);
-
- GetDItem(*myDialog, MASS_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).mass);
-
- GetDItem(*myDialog, INC_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).ink);
-
- GetDItem(*myDialog, SIM_NAME_VALUE, &itemType, &itemHndl, &itemRect);
- GetIText(itemHndl, &(**settings).simName);
- }
-
-
-
-
- postProcess(settings)
- SavedSettingsPtr *settings;
-
- /*
- Post Process parses all fields ret'd by input dialog to check for
- invalid characters. It returns a value of true to the calling routine
- if all the fields are correct.
- */
-
- {
- int num;
- Ptr chPtr;
- Str255 Astring;
-
- chPtr = (char *) &(**settings).frict;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
-
- chPtr = (char *) &(**settings).amp;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
-
- chPtr = (char *) &(**settings).elastic;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
-
- chPtr = (char *) &(**settings).start;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
- P2Cstr(chPtr, Astring);
- num = atoi(Astring); /* chk for -ive condition */
- if (num < 0)
- return(FALSE);
-
- chPtr = (char *) &(**settings).fini;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
- P2Cstr(chPtr, Astring);
- num = atoi(Astring); /* -ive || equal to 0 condition */
- if ((num < 0) || (num == 0))
- return(FALSE);
-
- chPtr = (char *) &(**settings).mass;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
- P2Cstr(chPtr, Astring);
- num = atoi(Astring);
- if ((num < 0) || (num == 0))
- return(FALSE);
-
- chPtr = (char *) &(**settings).ink;
- if (chkValid(chPtr) == FALSE) /* ret false if invalid char detected */
- return(FALSE);
- P2Cstr(chPtr, Astring);
- num = atoi(Astring);
- if ((num < 0) || (num == 0))
- return(FALSE);
-
- return(TRUE);
- }
-
-
-
-
- chkValid(cPtr)
- char *cPtr;
-
- /*
- checks pascal strings for non-numeric characters and returns true
- value if no invalid characters are detected.
- */
-
- {
- char ch;
- int i,
- length = 0,
- minusCount = 0,
- plusCount = 0,
- ptCount = 0;
-
- length = *cPtr; /* extract length of pascal string */
-
- if (length == 0)
- return(FALSE); /* zero length string */
-
- for (i = 1; i <= length; i++)
- {
- ch = *(cPtr + i);
- if ((ch >= '0') && (ch <= '9'))
- ;
- else
- {
- switch (ch)
- {
- case '.' :
- ptCount++;
- break;
- case '+' :
- plusCount++;
- break;
- case '-' :
- minusCount++;
- break;
- default :
- return(FALSE);
- break;
- }
- }
-
- /* return false if more than one detected */
-
- if ((ptCount > 1) || (plusCount > 1) || (minusCount > 1))
- return(FALSE);
- }
- return(TRUE);
- }
-
-
-
-
- PtoC(oldSettings, nuSettings)
- SavedSettingsPtr oldSettings, nuSettings;
-
- /*
- Pascal string to C string transforms the pascal strings in the structure
- oldSettings into C strings and places them into the structure nuSettings.
- */
-
- {
- P2Cstr((*oldSettings).frict, (*nuSettings).frict);
- P2Cstr((*oldSettings).amp, (*nuSettings).amp);
- P2Cstr((*oldSettings).elastic, (*nuSettings).elastic);
- P2Cstr((*oldSettings).start, (*nuSettings).start);
- P2Cstr((*oldSettings).fini, (*nuSettings).fini);
- P2Cstr((*oldSettings).xVal, (*nuSettings).xVal);
- P2Cstr((*oldSettings).yVal, (*nuSettings).yVal);
- P2Cstr((*oldSettings).mass, (*nuSettings).mass);
- P2Cstr((*oldSettings).ink, (*nuSettings).ink);
- P2Cstr((*oldSettings).simName, (*nuSettings).simName);
- }
-
-
-
-
- validateX(SettingsPtr)
- SavedSettingsPtr *SettingsPtr;
-
- /*
- Validate X checks to see if the differential of x is divisible by ten.
- If it is the function returns a true; otherwise it returns a value of false.
- */
-
- {
- double atof();
- int delta,
- aNumber;
- Str255 Start,
- Finish;
-
- P2Cstr((**SettingsPtr).fini, Finish); /* convert strs to C strings */
- P2Cstr((**SettingsPtr).start, Start);
-
- delta = atof(Finish) - atof(Start);
-
- aNumber = delta / 10;
- if(aNumber > 0)
- return(TRUE);
- else
- return(FALSE);
- }
-
-
-
-
- validateY(SettingsPtr)
- SavedSettingsPtr *SettingsPtr;
-
- /*
- Validate Y checks to see if the differential of y is divisible by eight.
- If it is the function returns a true; otherwise it returns a value of false.
- */
-
- {
- double atof();
- int aNumber;
- Str255 Amp;
-
- P2Cstr((**SettingsPtr).amp, Amp); /* convert pascal str to C str */
-
- aNumber = atof(Amp);
- if (aNumber >= 8)
- return(TRUE);
- else
- return(FALSE);
- }
-
-
-
-
- doStatus(Coeff, Mass, Elast, sName, win)
- double Coeff,
- Mass,
- Elast;
- Str255 *sName;
- WindowPtr *win;
-
- /*
- Do Status is used to either store information about the last
- simulation, or to display the status of the last simulation recorded.
- The action depends on the contents of the parameters passed to the
- routine.
- */
-
- {
- int currentRow = 12, leftMargin = 10, rowOffset = 24;
- Str255 num2str;
-
- static Boolean beenHereBefore = FALSE;
- static double b = NIL, bSqr = NIL, fourMK = NIL, k = NIL, m = NIL, omega = NIL;
- static Str255 NameOfLastSim;
-
- if ((Mass == NIL) && (beenHereBefore == TRUE))
- {
- /* update screen only */
-
- TextFont(1); /* change textfont to application */
-
- EraseRect(&(*win)->portRect);
- MoveTo(leftMargin, currentRow);
- DrawString("\pSimulation Name: ");
- DrawString(&NameOfLastSim);
- currentRow = currentRow + rowOffset;
- MoveTo(leftMargin, currentRow);
- DrawString("\pAngular Velocity: ");
- NumToString((long) omega, num2str);
- DrawString(num2str);
- currentRow = currentRow + rowOffset;
- MoveTo(leftMargin, currentRow);
- if (bSqr < fourMK)
- DrawString("\pThe function is underdamped");
- if (bSqr > fourMK)
- DrawString("\pThe function is overdamped");
- if (bSqr == fourMK)
- DrawString("\pThe function is critically damped");
-
- TextFont(NIL); /* reset font to default */
- return(TRUE);
- }
-
- if (Mass != NIL)
- {
- b = Coeff; /* save input from current simulation */
- m = Mass;
- k = Elast;
- C2Pstr(sName, NameOfLastSim);
- bSqr = b * b;
- fourMK = 4 * m *k;
- omega = (0.5 * m) * sqrt(fourMK - bSqr);
- beenHereBefore = TRUE;
- return(TRUE);
- }
- return(FALSE);
- }